﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
using System.IO;
using TSL_Tools.SqlTools;
using System.Diagnostics;

[assembly: CLSCompliant(true)]
namespace ReportingEngine
{
    public partial class TSL_ReportingEngine
    {
        /// <summary>
        /// Gets the Load Test structure XML from the LoadTestRun entry and puts it into the appropriate structures
        /// </summary>
        public TimeSpan GetLoadTestXML(string runId, ref LoadTestCoreInfo _info)
        {
            string sqlCmd = String.Format(Sql_GETLOADTESTBLOB, runId);
            DateTime dt = DateTime.Now;

            using (SqlConnection _conn = new SqlConnection(sqlConn))
            {
                _conn.Open();
                SqlCommand _cmd = new SqlCommand(sqlCmd, _conn);
                _cmd.CommandTimeout = cmdTimeout;

                SqlDataReader _rdr = _cmd.ExecuteReader();
                while (_rdr.Read())
                {
                    MemoryStream ms = new MemoryStream((byte[])_rdr.GetValue(0));
                    xDoc.Load(ms);
                }
                _rdr.Close();
                _cmd.Dispose();
            }
            ParseLoadTestXML(ref _info);
            return (TimeSpan)(DateTime.Now - dt);
        }

        private void ParseLoadTestXML(ref LoadTestCoreInfo info)
        {
            try
            {
                info.loadTestRunXmlAsString = xDoc.InnerXml;
                XmlElement xRoot = xDoc.DocumentElement;
                string sCurrentRunSettings = xRoot.GetAttribute("CurrentRunConfig");

                // -- Get the basic Run Settings --
                foreach (XmlElement item in xRoot["RunConfigurations"].ChildNodes)
                {
                    if (item.GetAttribute("Name") == sCurrentRunSettings)
                    {
                        GetTheRunSettings(item, ref info);
                    }
                }

                // -- Get all of the scenario data
                foreach (XmlElement item in xRoot["Scenarios"].ChildNodes)
                {
                    ProcessScenario(item, ref info);
                }
            }
            catch (XmlException ex)
            {
                Console.Write(ex.ToString());
            }
        }

        public string SaveLoadTestXML(int runId, string fileName)
        {
            string sqlCmd = String.Format(Sql_GETLOADTESTBLOB, runId);
            DateTime dt = DateTime.Now;

            using (SqlConnection _conn = new SqlConnection(sqlConn))
            {
                _conn.Open();
                SqlCommand _cmd = new SqlCommand(sqlCmd, _conn);
                _cmd.CommandTimeout = cmdTimeout;

                SqlDataReader _rdr = _cmd.ExecuteReader();
                while (_rdr.Read())
                {
                    MemoryStream ms = new MemoryStream((byte[])_rdr.GetValue(0));
                    xDoc.Load(ms);
                }
                _rdr.Close();
                _cmd.Dispose();
            }
            xDoc.Save(fileName);
            return String.Format("{0} Saved Successfully", fileName);
        }

        private static void GetTheRunSettings(XmlElement xElement, ref LoadTestCoreInfo info)
        {
            foreach (XmlAttribute attrib in xElement.Attributes)
            {
                info.runConfiguration.Add(attrib.Name, attrib.Value);
            }

            /*
            <RunConfiguration Name="Run Settings1" Description="" ....>
                <CounterSetMappings>
                    <CounterSetMapping ComputerName="Machine1"><CounterSetReferences><CounterSetReference CounterSetName="Application" /><CounterSetReference CounterSetName="ASP.NET" /><CounterSetReference CounterSetName=".NET Application" /><CounterSetReference CounterSetName="IIS" /></CounterSetReferences></CounterSetMapping>
                    <CounterSetMapping ComputerName="Machine2"><CounterSetReferences><CounterSetReference CounterSetName="SQL" /></CounterSetReferences></CounterSetMapping>
                    <CounterSetMapping ComputerName="[CONTROLLER MACHINE]"><CounterSetReferences><CounterSetReference CounterSetName="LoadTest" /><CounterSetReference CounterSetName="Controller" /></CounterSetReferences></CounterSetMapping>
                    <CounterSetMapping ComputerName="[AGENT MACHINES]"><CounterSetReferences><CounterSetReference CounterSetName="Agent" /></CounterSetReferences></CounterSetMapping>
                </CounterSetMappings>
            </RunConfiguration>
            */
            foreach (XmlElement item in xElement.ChildNodes)
            {
                if (item.Name == "CounterSetMappings")
                {
                    foreach (XmlElement subItem in item.ChildNodes)
                    {
                        if (!subItem.GetAttribute("ComputerName").StartsWith("["))
                        {
                            info.sutMachines.Add(subItem.GetAttribute("ComputerName"));
                        }
                    }
                }
            }

        }

        private static void ProcessScenario(XmlElement xElement, ref LoadTestCoreInfo info)
        {
            try
            {
                Dictionary<string, string> dict = new Dictionary<string, string>();
                string sName = xElement.Attributes["Name"].Value;

                // ----- get the core attributes
                foreach (XmlAttribute attrib in xElement.Attributes)
                {
                    dict.Add(attrib.Name, attrib.Value);
                }

                // ----- get the think profile (BUG: Hardcoded child nodes. This will break if the schema changes)
                dict.Add("ThinkPattern", xElement.ChildNodes[0].Attributes["Pattern"].Value);

                // ----- get the load profile info
                string sLoadProfile = "";
                foreach (XmlAttribute attrib in xElement.ChildNodes[1].Attributes)
                {
                    sLoadProfile += String.Format("\"{0}\"=\"{1}\", ", attrib.Name, attrib.Value);
                }
                dict.Add("LoadProfile", sLoadProfile);

                // ----- Add all of the tests to the mix
                string sTestMix = "";

                for (int a = 0; a < xElement.ChildNodes.Count; a++)
                {
                    if (xElement.ChildNodes[a].Name == "TestMix")
                    {
                        foreach (XmlElement xSubElement in xElement.ChildNodes[a].ChildNodes)
                        {
                            sTestMix += String.Format("[{1}%]\t{0};"
                                , xSubElement.Attributes["Name"].Value, xSubElement.Attributes["Percentage"].Value);
                        }
                    }
                    else if (xElement.ChildNodes[a].Name == "TerminateTest")
                    {
                        foreach (XmlElement xSubElement in xElement.ChildNodes[a].ChildNodes)
                        {
                            sTestMix += String.Format("{1}\t{0};"
                                , xSubElement.Attributes["Name"].Value, "Terminate Test");
                        }
                    }
                    else if (xElement.ChildNodes[a].Name == "InitializeTest")
                    {
                        foreach (XmlElement xSubElement in xElement.ChildNodes[a].ChildNodes)
                        {
                            sTestMix += String.Format("{1}\t{0};"
                                , xSubElement.Attributes["Name"].Value, "Initialize Test");
                        }
                    }
                }
                dict.Add("TestMix", sTestMix.Substring(0, sTestMix.Length - 1));  // strip out the last semi-colon

                // ----- Add this scenario to the list
                info.scenarios.Add(sName, dict);
            }
            catch (Exception ex)
            {
                string str = String.Format("ProcessScenario failed for run {0}\r\n\r\n Exception:\r\n{1}\r\n{2}",
                    info.runId, ex.Message, ex.StackTrace);
                //File.WriteAllText("c:\\temp\\debuglog.txt", str);
                info.resultTypes = info.resultTypes | ResultTypesStoredInLoadTest.LoadTestParsingFailed;
                Debug.Write(str);
            }
        }
    }
}

